﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TreeGrid
{
	public class TreeGridView : DataGridView
	{
		public TreeGridView()
		{
			this.RowHeadersWidth = 55;
			//this.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;

			//this.CellPainting += DataGridTreeView_CellPainting;
			this.RowPostPaint += DataGridTreeView_RowPostPaint;

			//this.RowsAdded += DataGridTreeView_RowsAdded;
		}

		private void DataGridTreeView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
		{
			TreeGridViewRow row = this.Rows[e.RowIndex] as TreeGridViewRow;
			if (row == null)
				return;

			Pen pen = new Pen(SystemColors.ControlDark, 1.0f);
			pen.DashStyle = DashStyle.Dot;

			if (row.ParentRow != null && row.Visible)
			{
				TreeGridViewRow prow = row.ParentRow;

				while (prow != null)
				{
					if (!prow.IsParentLastChild && prow.ParentRow != null)
					{
						int x = 18 + (prow.Layer - 1) * 13 + 6;
						Point pts = new Point(x, e.RowBounds.Top);
						Point pte = new Point(x, e.RowBounds.Bottom);

						e.Graphics.DrawLine(pen, pts, pte);
					}

					prow = prow.ParentRow;
				}
			}

			if (row.HasChildren)
			{
				int x = 18 + row.Layer * 13;
				int top = e.RowBounds.Top + (row.Height - 13) / 2;
				Rectangle rc = new Rectangle(x, top, 13, 13);
				DrawTreeIcon(e.Graphics, rc, row.IsExpand);

				x += 13;
				top += 6;
				//Rectangle rc = new Rectangle(x, top, 13, 13);
				Point pts = new Point(x, top);
				Point pte = new Point(this.RowHeadersWidth, top);
				e.Graphics.DrawLine(pen, pts, pte);

				if (row.IsExpand)
				{
					x -= 7;
					top += 7;
					//Rectangle rc = new Rectangle(x, top, 13, 13);
					pts = new Point(x, top);
					pte = new Point(x, e.RowBounds.Bottom);
					e.Graphics.DrawLine(pen, pts, pte);
				}

				if (row.ParentRow != null)
				{
					x = 18 + (row.Layer - 1) * 13 + 6;
					top = e.RowBounds.Top + row.Height / 2;

					pts = new Point(x, e.RowBounds.Top);

					if (row.IsParentLastChild)
					{
						pte = new Point(x, top);
						e.Graphics.DrawLine(pen, pts, pte );

						pts = pte;
						pte = new Point(x + 6, top);
						e.Graphics.DrawLine(pen, pts, pte);
					}
					else
					{
						pte = new Point(x, e.RowBounds.Bottom);
						e.Graphics.DrawLine(pen, pts, pte);

						pts = new Point(x, top);
						pte = new Point(x + 6, top);
						e.Graphics.DrawLine(pen, pts, pte);
					}
				}
			}
			if (row.ParentRow != null && row.Visible && !row.HasChildren)
			{
				int x = 18 + (row.Layer - 1) * 13 + 6;
				//Rectangle rc = new Rectangle(x, top, 13, 13);
				Point pts = new Point(x, e.RowBounds.Top);

				Point pte = new Point(x, e.RowBounds.Bottom);
				if (row.IsParentLastChild)
					pte.Y = e.RowBounds.Top + e.RowBounds.Height / 2;

				e.Graphics.DrawLine(pen, pts, pte);

				int top = e.RowBounds.Top + e.RowBounds.Height / 2;
				pts = new Point(x, top);
				pte = new Point(this.RowHeadersWidth, top);
				e.Graphics.DrawLine(pen, pts, pte);
			}
		}

		// 绘制行头、列头
		//private void DataGridTreeView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
		//{
		//	if (e.ColumnIndex == -1 && e.RowIndex == -1)
		//	{
		//		using (LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.LightGray,
		//			Color.White, LinearGradientMode.ForwardDiagonal))
		//		{
		//			e.Graphics.FillRectangle(brush, e.CellBounds);
		//			Rectangle border = e.CellBounds;
		//			border.Offset(new Point(-1, -1));
		//			e.Graphics.DrawRectangle(Pens.Gray, border);
		//		}
		//		e.PaintContent(e.CellBounds);
		//		e.Handled = true;
		//	}
		//	else if (e.RowIndex == -1)
		//	{
		//		//标题行
		//		using (LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.LightGray,
		//			Color.White, LinearGradientMode.Vertical))
		//		{
		//			e.Graphics.FillRectangle(brush, e.CellBounds);
		//			Rectangle border = e.CellBounds;
		//			border.Offset(new Point(-1, -1));
		//			e.Graphics.DrawRectangle(Pens.Gray, border);
		//		}
		//		e.PaintContent(e.CellBounds);
		//		e.Handled = true;
		//	}
		//	else if (e.ColumnIndex == -1)
		//	{
		//		//标题列
		//		using (LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.LightGray,
		//			Color.White, LinearGradientMode.Horizontal))
		//		{
		//			e.Graphics.FillRectangle(brush, e.CellBounds);
		//			Rectangle border = e.CellBounds;
		//			border.Offset(new Point(-1, -1));
		//			e.Graphics.DrawRectangle(Pens.Gray, border);
		//		}
		//		e.PaintContent(e.CellBounds);
		//		e.Handled = true;
		//	}
		//}

		protected override void OnCellFormatting(DataGridViewCellFormattingEventArgs e)
		{
			base.OnCellFormatting(e);

			//if (e.ColumnIndex == 0)
			//{
			//	TreeGridViewRow row = this.Rows[e.RowIndex] as TreeGridViewRow;
			//	if (row == null)
			//		return;

			//	int iLayer = 0;

			//	TreeGridViewRow parent = row.ParentRow;

			//	string sPreText = "";
			//	while (parent != null)
			//	{
			//		iLayer++;
			//		sPreText += "  ";
			//		parent = parent.ParentRow;
			//	}

			//	e.Value = sPreText + row.Cells[0].Value;
			//}
		}

		protected override void OnRowHeaderMouseClick(DataGridViewCellMouseEventArgs e)
		{
			base.OnRowHeaderMouseClick(e);

			TreeGridViewRow row = this.Rows[e.RowIndex] as TreeGridViewRow;
			if (row == null || !row.HasChildren)
				return;

			Rectangle bounds = new Rectangle(0, 0, this.RowHeadersWidth, row.Height);
			int top = (row.Height - 13) / 2;

			int x = 18 + row.Layer * 13;
			Rectangle rc = new Rectangle(x, top, 13, 13);
			if (rc.Contains(e.Location))
			{
				row.IsExpand = !row.IsExpand;
			}
		}

		protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
		{
			if (e.RowIndex < 0 || e.RowCount <= 0)
				return;

			List<DataGridViewRow> lstRow = new List<DataGridViewRow>();
			for (int i = e.RowIndex; i < e.RowIndex + e.RowCount; i++)
			{
				lstRow.Add(this.Rows[i]);
			}

			foreach (var r in lstRow)
			{
				TreeGridViewRow row = r as TreeGridViewRow;
				if (row == null || !row.HasChildren)
					return;

				int index = Rows.IndexOf(r);
				//int index = e.RowIndex;
				foreach (var subRow in row.ChildRows)
				{
					if (!this.Rows.Contains(subRow))
					{
						index++;
						this.Rows.Insert(index, subRow);
						index += subRow.ChildRowCount();
					}
				}
			}
		}


		protected void DrawTreeIcon(Graphics g, Rectangle rc, bool bExpand)
		{
			if (g == null)
				return;

			rc.Inflate(-1, -1);
			rc.Width -= 1;
			rc.Height -= 1;
			//Pen p = new Pen(SystemPens)
			g.DrawRectangle(SystemPens.ControlDarkDark, rc);

			Point ptS = rc.Location;
			ptS.X += 2;
			ptS.Y += 5;

			Point ptE = ptS;
			ptE.X += 6;

			g.DrawLine(SystemPens.ControlDarkDark, ptS, ptE);

			if (!bExpand)
			{
				ptS = rc.Location;
				ptS.X += 5;
				ptS.Y += 2;

				ptE = ptS;
				ptE.Y += 6;
				g.DrawLine(SystemPens.ControlDarkDark, ptS, ptE);
			}
		}
	}
}
